home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-10-18 | 11.6 KB | 552 lines | [TEXT/CWIE] |
- /*
- * Shell.cp
- *
- * SuperSplash
- * ^^^^^^^^^^^
- * Main shell for application
- * © Andrew Nemeth (where applicable), Warrimoo Australia 1994, 1995
- * aznemeng@zeta.org.au
- *
- * File created: 3 Oct 95.
- * Modified: 3, 18 Oct 95.
- */
-
- #include "gConstDefines.h" // Global #defines & const's
- #include "gVariables.h" // Global variable defn & 'externs'
- #include "stdHighLevelApple.h" // Application High-Level AE
-
- #include "AZN_DBUG.H" // debugging utilites
- #include "AZN_TSuperSplash.h" // put up & manage Splash screen
-
- #include <AppleEvents.h> // Mac high level AE
- #include <AEObjects.h> // mac OSL constants
- #include <LowMem.h>
- #include <Gestalt.h>
- #include <Balloons.h> // Access to System 7 help menu
- #include <limits.h> // For LONG_MAX
-
-
- // FILE DEFINES…
- //
-
- // 'stopMask' parameter in '::FlushEvents()'
- const short kshZapEvents = 0;
-
-
- // PROGRAM GLOBALS
- //
- struct myGlobalStruct * gptrGlobalsRec = NULL;
-
-
- // FILE GLOBALS
- //
- static MenuHandle ghMenus[ kMenusInBar ];
- static Boolean gboolUpdateMenus;
- static RgnHandle ghMouseRgn;
-
- // Globals used to “tune” the performance of MainEventLoop
- // (assume we’ll be starting in the foreground)
-
- static unsigned long gulgRunQuantum;
- static unsigned long gulgSleepQuantum;
-
-
-
- // FILE FUNCTIONS…
- //
- static void toolBoxInit ( void );
- static void assignProgGlobals ( void );
- static void menuBarInit ( void );
- static void eventLoop ( void );
- static void doEvent ( EventRecord * );
-
- static void doMouseDown ( EventRecord * );
- static void doMenuChoice ( long );
- static void doAppleChoice ( short );
- static void doFileChoice ( short );
- static void doOptionsChoice ( short );
-
- static void doKeyPress ( EventRecord * );
- static void maintainMenus ( Boolean );
- static void quitNow ( void );
-
-
-
- void main( void )
- //
- {
- OSErr myErr;
- long lgFeature;
-
-
- toolBoxInit();
-
- INIT_DEBUG();
- // MUST be system 7!
- myErr = ::Gestalt( gestaltSystemVersion, &lgFeature );
- if ( myErr == noErr && ( lgFeature < 0x0700 ) )
- ExitToShell();
- // need QuickTime for JPEG images
- myErr = ::Gestalt( gestaltQuickTimeVersion, &lgFeature );
- if ( ( myErr == noErr ) && ( lgFeature < 0x0200 ) )
- {
- ::Alert( kresidALRT_QuickTime, NULL );
- }
-
- assignProgGlobals();
-
- menuBarInit();
-
- eventLoop();
- }
-
-
-
- void toolBoxInit( void )
- //
- // Initialise toolbox and memory
- //
- {
- ::InitGraf( &qd.thePort );
- ::InitFonts( );
- ::FlushEvents( everyEvent, kshZapEvents );
- ::InitWindows( );
- ::TEInit( );
- ::InitDialogs( 0L );
- ::InitCursor( );
- // cut down on heap fragmentation
- ::MaxApplZone( );
- ::MoreMasters( );
- ::MoreMasters( );
- // fire up high leve AE
- highLevelEventInit();
- }
-
-
-
- void assignProgGlobals( void )
- //
- // A single place to assign all
- // program–wide globals
- //
- {
- // create global struct on heap
- gptrGlobalsRec = (myGlobalStruct *)::NewPtrClear( sizeof( myGlobalStruct ) );
-
- // Note on the above
- // Don't use 'gptrGlobalsRec = new struct myGlobalStruct;' !
- // Operator new in ANSI library allocates blocks of
- // memory in 65532 byte slabs. As this global will be
- // hanging around for the entire program, it is
- // much more efficient to only allocate a ptr of
- // size 352 bytes (or so).
- //
- // initialise global values
- if ( gptrGlobalsRec )
- {
- gptrGlobalsRec->boolDone = FALSE;
- // event 'tuning' globals
- gptrGlobalsRec->foregroundRunQuantum = 0L;
- gptrGlobalsRec->foregroundSleepQuantum = GetCaretTime( );
- gptrGlobalsRec->backgroundRunQuantum = 0L;
- gptrGlobalsRec->backgroundSleepQuantum = LONG_MAX;
- }
- }
-
-
- void menuBarInit( void )
- //
- // Install about menu and then
- // zap all items in menubar
- //
- {
- MenuHandle hMenu = NULL;
- Handle hMenuBar = NULL;
-
-
- hMenuBar = ::GetNewMBar( kMenuBar_ID );
- ASSERT( hMenuBar != nil );
-
- ::SetMenuBar( hMenuBar );
- // assign Global MenuHandle Array
- for ( short i = kAppleNdx, j = kMApple_ID; i < kMenusInBar ; i++, j++ )
- {
- ghMenus[ i ] = (MenuHandle)::GetMenu( j );
- ASSERT( ghMenus[ i ] != nil );
- }
- // insert 'About Application' into apple Menu
- hMenu = ::GetMHandle( kMApple_ID );
- ASSERT( hMenu != nil );
-
- ::AddResMenu( hMenu, 'DRVR' );
-
- ::DrawMenuBar( );
- gboolUpdateMenus = FALSE;
- }
-
-
-
- void eventLoop( void )
- //
- // Main event handling loop
- //
- {
- EventRecord erRec;
- unsigned long ulgCheckEvents = 0L;
-
-
- gulgRunQuantum = gptrGlobalsRec->foregroundRunQuantum;
- gulgSleepQuantum = gptrGlobalsRec->foregroundSleepQuantum;
- ghMouseRgn = nil;
- gboolUpdateMenus = TRUE;
-
- gptrGlobalsRec->boolDone = FALSE;
-
- while ( ! gptrGlobalsRec->boolDone )
- {
- if ( gulgRunQuantum == 0 || ( ::TickCount( ) > ulgCheckEvents ) )
- {
- ulgCheckEvents = ::TickCount() + gulgRunQuantum;
- ::WaitNextEvent( everyEvent, &erRec, gulgSleepQuantum, ghMouseRgn );
- doEvent( &erRec );
- }
- }
- // final tidy-up prior to exit
- quitNow();
- }
-
-
-
-
- void doEvent( EventRecord *ptrEventRec )
- //
- // Events are first dealt with here
- // Note: most of these events are processed
- // in the individual dialogFilter procedures!
- //
- {
- switch ( ptrEventRec->what )
- {
- // null events
- case nullEvent:
- break;
- // see 'stdHighLevelApple.cp'
- case kHighLevelEvent:
- ::AEProcessAppleEvent( ptrEventRec );
- break;
- // key press
- case autoKey:
- case keyDown:
- doKeyPress( ptrEventRec );
- break;
- // rat press
- case mouseDown:
- doMouseDown( ptrEventRec );
- break;
- // not handled
- case activateEvt:
- case updateEvt:
- break;
- // disc insertions
- case diskEvt:
- if ( ptrEventRec->message >> 16 )
- {
- static Point where = { 50, 50 };
- ::DIBadMount( where, ptrEventRec->message );
- }
- break;
- // multi-finder foreground/ background
- case osEvt:
- switch ( ( ptrEventRec->message & osEvtMessageMask ) >> 24 )
- {
- case mouseMovedMessage:
- break;
-
- case suspendResumeMessage:
- if ( ptrEventRec->message & resumeFlag )
- {
- ::SetCursor( &qd.arrow );
-
- gulgRunQuantum = gptrGlobalsRec->foregroundRunQuantum;
- gulgSleepQuantum = gptrGlobalsRec->foregroundSleepQuantum;
- }
- else
- {
- gulgRunQuantum = gptrGlobalsRec->backgroundRunQuantum;
- gulgSleepQuantum = gptrGlobalsRec->backgroundSleepQuantum;
- }
- break;
- }
- break;
- }
- // update menus when there's an interesting event
- if ( ptrEventRec->what != nullEvent && gboolUpdateMenus )
- maintainMenus( TRUE );
- }
-
-
-
- void doMouseDown( EventRecord *ptrEventRec )
- //
- // Someone squeezed the rat…
- //
- {
- WindowPtr ptrWindow;
- short thePart;
- long lgMenuChoice;
-
-
- thePart = ::FindWindow( ptrEventRec->where, &ptrWindow );
- switch( thePart )
- {
- // menu selected
- case inMenuBar:
- lgMenuChoice = ::MenuSelect( ptrEventRec->where );
- doMenuChoice( lgMenuChoice );
- break;
- // window dragged about - not handled
- case inDrag:
- case inContent:
- break;
- // DA's
- case inSysWindow:
- ::SystemClick( ptrEventRec, ptrWindow );
- gboolUpdateMenus = TRUE;
- break;
- }
- }
-
-
-
- void doMenuChoice( long lgMenuChoice )
- //
- // Menu chosen
- //
- {
- short menu;
- short shMenuItem;
-
-
- if ( lgMenuChoice != 0 )
- {
- // Macros to break 4-byte value into 2 shorts
- menu = HiWord( lgMenuChoice );
- shMenuItem = LoWord( lgMenuChoice );
-
- switch( menu )
- {
- case kMApple_ID:
- doAppleChoice( shMenuItem );
- break;
-
- case kMFile_ID:
- doFileChoice( shMenuItem );
- break;
-
- case kMOptions_ID:
- doOptionsChoice( shMenuItem );
- break;
- // system 7 Help menu - not handled
- case kHMHelpMenuID:
- break;
- // catch-all escape to quit application
- default:
- quitNow( );
- break;
- }
- ::HiliteMenu( 0 );
- }
- }
-
-
-
- void doAppleChoice( short shMenuItem )
- //
- // 'About Application' chosen or DA
- //
- {
- MenuHandle appleMenu = NULL;
- Str255 accName = { kEmptyString };
- short accNumber;
-
-
- switch ( shMenuItem )
- {
- case kM_About:
- // knockout highlight on apple menu
- ::FlashMenuBar( kMApple_ID );
- ::NoteAlert( kresidALRT_About, kNilFilterProc );
- gboolUpdateMenus = TRUE;
- break;
- // existing Apple Menus
- default:
- appleMenu = ::GetMHandle( kMApple_ID );
- ::GetItem( appleMenu, shMenuItem, accName );
- accNumber = ::OpenDeskAcc( accName );
- gboolUpdateMenus = TRUE;
- break;
- }
- }
-
-
-
- void doFileChoice( short shMenuItem )
- //
- // Parse 'File' menu choice
- //
- {
- switch( shMenuItem )
- {
- // signal ready for quit
- case kM_Quit:
- default:
- gptrGlobalsRec->boolDone = TRUE;
- break;
- }
- }
-
-
-
- void doOptionsChoice( short shMenuItem )
- //
- // Parse 'Options' menu choice
- //
- {
- ConstStr63Param kstr63JPEGName = { "\pIMAGE.jpeg" },
- kstr36PICTName = { "\pIMAGE.pict" };
- const short kshPICT_Res_ID = 2000;
-
- TSuperSplash * ptrobjSplash = NULL;
- Boolean boolSplashSuccess = FALSE;
- OSErr myErr = noErr;
-
-
- // Show-off the three ways of splashing an image
-
- switch( shMenuItem )
- {
- // Given the name of a JPEG file in the same directory
- // as the application, use the image in it as that
- // for the splashscreen
- //
- case kM_Splash_JPEG_file:
- ptrobjSplash = new TSuperSplash( kstr63JPEGName );
- break;
-
- // Do the same for a PICT file
- //
- case kM_Splash_PICT_file:
- ptrobjSplash = new TSuperSplash( kstr36PICTName );
- break;
-
- // Splash a PICT resource located in the
- // application's resource fork
- //
- case kM_Splash_PICT_resource:
- ptrobjSplash = new TSuperSplash( kshPICT_Res_ID );
- break;
- // catch-all in case of stupidity!
- default:
- quitNow();
- break;
- }
- // get image on screen
- boolSplashSuccess = ptrobjSplash->showSplash();
- // stall until mouse click
- if ( boolSplashSuccess )
- {
- ::SetCursor( &qd.arrow );
- while ( ! ::Button() )
- NULL;
- ::FlushEvents( mDownMask, kshZapEvents );
- }
- else
- ::SysBeep(1);
- // N.B. Failure will happen if:
- // 1. TSuperSplash couldn't find the file in question
- // 2. Tried to splash a JPEG file & there is no QuickTime installed
- // 3. Usual resource or file error (image file corrupted)
-
- // get rid of splash screen
- ptrobjSplash->killSplash();
-
- delete ptrobjSplash;
- gboolUpdateMenus = TRUE;
- }
-
-
-
- void doKeyPress( EventRecord *ptrEventRec )
- //
- // Respond to cmd-'' keypresses
- //
- {
- register char chCharPressed;
-
-
- chCharPressed = ptrEventRec->message & charCodeMask;
-
- if ( ( ptrEventRec->modifiers & cmdKey ) != 0 )
- {
- // quit now 'cmd-/' key press
- if ( chCharPressed == '/' && ptrEventRec->modifiers & cmdKey )
- quitNow( );
- else
- doMenuChoice( MenuKey( chCharPressed ) );
- }
- }
-
-
-
- void maintainMenus( Boolean boolEnableAll )
- //
- // Make sure menus reflect
- // current state of application
- // If 'boolEnableAll' is FALSE, then menubar
- // is deactivated
- //
- {
- const short kshDoForAll = 0;
- short i;
-
-
- // Enable/ disable all menu bar headings
- //
- for ( i = kAppleNdx; i < kMenusInBar ; i++ )
- {
- if ( boolEnableAll )
- ::EnableItem( ghMenus[ i ], kshDoForAll );
- else
- ::DisableItem( ghMenus[ i ], kshDoForAll );
- }
-
- // enable/ disable individual items
- if ( boolEnableAll )
- {
- // always activate
- ::EnableItem( ghMenus[ kFileNdx ], kM_Quit );
-
- ::EnableItem( ghMenus[ kOptionsNdx ], kM_Splash_JPEG_file );
- ::EnableItem( ghMenus[ kOptionsNdx ], kM_Splash_PICT_file );
- ::EnableItem( ghMenus[ kOptionsNdx ], kM_Splash_PICT_resource );
- // wait for update!
- ::InvalMenuBar( );
- }
- // deactivate mbar NOW!
- else
- ::DrawMenuBar( );
-
- gboolUpdateMenus = FALSE;
- }
-
-
-
- void quitNow( void )
- //
- // When the cmd—'/' is pressed,
- // things to do before exit
- //
- {
- gptrGlobalsRec->boolDone = TRUE;
- }
-